package org.iabako.server.tools.pdftable;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.iabako.shared.tools.GenericTools;

import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;

/**
 * Created by jose on 05/02/15.
 */
public class PdfWriterHelper {

    public final static java.awt.Color gray = new java.awt.Color(240, 240, 240);
    public final static java.awt.Color lightGray = new java.awt.Color(250, 250, 250);
    public final static int CONTACT_TABLE_WIDTH = 250;

    public float top;
    public float initMargin;
    public float margin;
    public PDDocument doc;
    public PDPage page;
    public PDPageContentStream pageContentStream;

    private String footerDate;
    private String footerPageCounter;

    private java.util.Map<PdfTable, PdfRow> footers = new LinkedHashMap<PdfTable, PdfRow>();
    private java.util.List<PDPageContentStream> pageContentStreams = new ArrayList<PDPageContentStream>();

    public PdfWriterHelper(float margin, PDDocument doc, String footerDate, String footerPageCounter) throws IOException {
        this.margin = margin;
        this.initMargin = margin;
        this.doc = doc;
        this.footerDate = footerDate;
        this.footerPageCounter = footerPageCounter;

        addNewPage();
    }

    public void addFooter() throws IOException {

        float tableWidth = getPageContentWidth();

        pageContentStream.setLineWidth(2);
        pageContentStream.setStrokingColor(Color.BLACK);
        pageContentStream.drawLine(initMargin, 30, initMargin + tableWidth, 30);
        pageContentStream.closeSubPath();

        PdfTable footer = new PdfTable(30, initMargin, page, pageContentStream);
        footer.setLineColor(Color.WHITE);
        footer.setLineWidth(0);

        PdfRow footerRow = new PdfRow(15f);
        PdfCell cell = new PdfCell(262, footerDate + " " + GenericTools.formatTime(new Date()));
        cell.setFontSize(7);
        cell.setFont(PDType1Font.HELVETICA);
        cell.setFillColor(Color.WHITE);
        cell.setTextColor(Color.DARK_GRAY);
        footerRow.addCell(cell);
        cell = new PdfCell(140, "");
        cell.setFontSize(7);
        cell.setFont(PDType1Font.HELVETICA);
        cell.setFillColor(Color.WHITE);
        cell.setTextColor(Color.DARK_GRAY);
        footerRow.addCell(cell);
        cell = new PdfCell(170, "Powered by IABAKO | www.iabako.com");
        cell.setFontSize(7);
        cell.setRightAlign(true);
        cell.setFont(PDType1Font.HELVETICA);
        cell.setFillColor(Color.WHITE);
        cell.setTextColor(Color.DARK_GRAY);
        footerRow.addCell(cell);

        footers.put(footer, footerRow);
    }

    public void addNewPage() throws IOException {
        page = new PDPage();
        doc.addPage(page);
        top = page.findMediaBox().getHeight() - margin;
        pageContentStream = new PDPageContentStream(doc, page, true, true);
        pageContentStreams.add(pageContentStream);
        addFooter();
    }

    public void moveTopPointer(float newTopOffset) throws IOException {
        moveTopPointer(null, newTopOffset);
    }

    public PdfTable moveTopPointer(PdfTable pdfTable, float newTopOffset) throws IOException {
        if (top - 70 > newTopOffset) {
            top -= newTopOffset;
        } else {
            addNewPage();
            if (pdfTable != null) {
                PdfTable newPdfTable = new PdfTable(this);
                newPdfTable.setLineColor(pdfTable.getLineColor());
                newPdfTable.setLineWidth(pdfTable.getLineWidth());
                pdfTable = newPdfTable;
            }
        }
        return pdfTable;
    }

    public void endFile() throws IOException {
        int counter = 1;
        for (PdfTable footer : footers.keySet()) {
            PdfRow footerRow = footers.get(footer);
            footerRow.getCells().get(1).setText(footerPageCounter.replace("{0}", counter++ + "").replace("{1}", footers.size() + ""));
            footer.drawRow(footerRow);
            footer.endTable();
        }

        for (PDPageContentStream pdPageContentStream : pageContentStreams) {
            pdPageContentStream.close();
        }
    }

    public static float getHeightOfCell(PdfCell cell, float horizontalMargin, float verticalMargin, float fontSize) throws IOException {
        int linesNumber = cell.getParagraph(horizontalMargin).getLines().size();
        return linesNumber * fontSize + verticalMargin * 2 + (linesNumber - 1) * 1.2f;
    }

    public float getPageContentWidth() {
        return getPageWidth() - initMargin * 2;
    }

    public float getPageWidth() {
        return page.findMediaBox().getWidth();
    }
}
